<?
require("core/base.php");


function getInfo()
{
    global $uptime, $sysname, $nodename, $release, $version, $machine, $username;
    
    $s="\nSupplied information:\n";
    $s.="uptime: ".$uptime." (".niceUptime($uptime).")\n";
    $s.="sysname: ".$sysname."\n";
    $s.="nodename: ".$nodename."\n";
    $s.="release: ".$release."\n";
    $s.="version: ".$version."\n";
    $s.="machine: ".$machine."\n";
    $s.="username: ".$username."\n";
    $s.="\n\n";
    return $s;
}

// uptime.php registers uptime information sent by uptimecl

$_MAX_FORWARD_DEVIATION=6000; // 5m
$_REBOOT_THRESHOLD=600; // 10m


// Let's check some things :)

// missing params?
if (!isset($_REQUEST['uptime']) ||
    !isset($_REQUEST['sysname']) ||
    !isset($_REQUEST['nodename']) ||
    !isset($_REQUEST['release']) ||
    !isset($_REQUEST['version']) ||
    !isset($_REQUEST['machine']) ||
    !isset($_REQUEST['username']) ||
    !isset($_REQUEST['pass']))
{
    echo("01 Missing parameters");
    mail("zouave@mansoft.org", "uptime", "Missing params\n\n".var_dump($_REQUEST));
    die;
}


// make life easier
$uptime=$_REQUEST['uptime'];
$sysname=$_REQUEST['sysname'];
$nodename=$_REQUEST['nodename'];
$release=$_REQUEST['release'];
$version=$_REQUEST['version'];
$machine=$_REQUEST['machine'];
$username=$_REQUEST['username'];
$pass=$_REQUEST['pass'];


// required values missing?
if (strlen(trim($uptime))==0 ||
    strlen(trim($username))==0 ||
    strlen(trim($nodename))==0)
{
    echo("02 Required values missing");
    mail("zouave@mansoft.org", "uptime", "Values missing\n\n".getInfo());
    die;
}


// username + pass
$bd=new bd;

$sQuery="SELECT COUNT(*) AS res FROM users WHERE username=".dbstr($username)." AND password=".dbstr(md5($pass));
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 01 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    echo("03 Authentication failed");
    mail("zouave@mansoft.org", "uptime", "Auth failed:\n\n".getInfo());    
    die;
}



// insert necessary data
$bd->query("BEGIN TRANSACTION;");

// insert machine data if necessary
$sQuery="SELECT COUNT(*) AS res FROM machines WHERE username=".dbstr($username)." AND name=".dbstr($nodename);
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 02 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    $sQuery="INSERT INTO machines(username, name) VALUES(".dbstr($username).", ".dbstr($nodename).")";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	echo("90 03 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	$bd->query("ROLLBACK");
	die;
    }    
    
    $sQuery="INSERT INTO uptime_regdate_stats(username, machine, max_reg_date) VALUES(".dbstr($username).", ".dbstr($nodename).", NOW())";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	echo("90 03 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	$bd->query("ROLLBACK");
	die;
    }    
    
}




// insert OS data if necessary
$sQuery="SELECT COUNT(*) AS res FROM os WHERE name=".dbstr($sysname);
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 04 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    $sQuery="INSERT INTO os(name) VALUES(".dbstr($sysname).")";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	$bd->query("ROLLBACK");
	echo("90 05 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }    
}


// version data
$sQuery="SELECT COUNT(*) AS res FROM versions WHERE os=".dbstr($sysname)." AND version=".dbstr($release);
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 06 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    $sQuery="INSERT INTO versions(version, os) VALUES(".dbstr($release).", ".dbstr($sysname).")";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	$bd->query("ROLLBACK");
	echo("90 07 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }    
}


// subversion data
$sQuery="SELECT subversion, COUNT(*) AS res FROM subversions WHERE info=".dbstr($version)." AND version=".dbstr($release)." AND os=".dbstr($sysname)." GROUP BY subversion";
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 08 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    $sQuery="INSERT INTO subversions(os, version, info) VALUES(".dbstr($sysname).", ".dbstr($release).", ".dbstr($version).")";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	$bd->query("ROLLBACK");
	echo("90 09 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }
        
    $sQuery="SELECT last_value FROM subversions_subversion_seq";
    $bd->query($sQuery);
    $r=$bd->getResultatObj();
    $subversionid=$r[0]->last_value;
    
    if ($bd->getErrDescr()!="Ok")
    {
	echo("90 10 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }    
}
else
    $subversionid=$r[0]->subversion;


// insert CPU data if necessary
$sQuery="SELECT COUNT(*) AS res FROM cpus WHERE cpu=".dbstr($machine);
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 11 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    $sQuery="INSERT INTO cpus(cpu) VALUES(".dbstr($machine).")";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	$bd->query("ROLLBACK");
	echo("90 12 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }    
}


// insert configuration data if necessary
$sQuery="SELECT COUNT(*) AS res FROM configurations WHERE username=".dbstr($username)." AND machine=".dbstr($nodename)." AND subversion=".dbstr($subversionid)." AND cpu=".dbstr($machine)." AND fin_date IS NULL";
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 13 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}

if ($r[0]->res==0)
{
    // close old configuration and insert new one
    $sQuery="UPDATE configurations SET fin_date=NOW() WHERE fin_date IS NULL AND username=".dbstr($username)." AND machine=".dbstr($nodename).";";
    $sQuery.="INSERT INTO configurations(username, machine, ini_date, fin_date, subversion, cpu) VALUES(";
    $sQuery.=dbstr($username).", ".dbstr($nodename).", NOW(), NULL, ".dbstr($subversionid).", ".dbstr($machine).");";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	$bd->query("ROLLBACK");
	echo("90 14 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }    
}


// commit current transaction
$bd->query("COMMIT");
if ($bd->getErrDescr()!="Ok")
{
    $bd->query("ROLLBACK");
    echo("90 15 Database error: ".$bd->getErrDescr());    
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}    





// insert or update uptime register

$sQuery="SELECT COUNT(*) AS res FROM uptime WHERE username=".dbstr($username)." AND machine=".dbstr($nodename);
$bd->query($sQuery);

$r=$bd->getResultatObj();

if ($bd->getErrDescr()!="Ok")
{
    echo("90 16 Database error: ".$bd->getErrDescr());
    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
    die;
}


$ipaddr=$_SERVER['REMOTE_ADDR'];	

if ($r[0]->res==0)
{
    // First uptime register    
    $sQuery="INSERT INTO uptime(username, machine, reg_date, uptime, ip) VALUES(";
    $sQuery.=dbstr($username).", ".dbstr($nodename).", NOW(), ".dbstr($uptime).", ".dbstr($ipaddr).")";
    $bd->query($sQuery);
    
    if ($bd->getErrDescr()!="Ok")
    {
	echo("90 17 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }    
}
else
{
    // get last uptime register
    $sQuery="SELECT uptime, reg_date FROM uptime WHERE username=".dbstr($username)." AND machine=".dbstr($nodename)." ORDER BY reg_date DESC LIMIT 1 OFFSET 0";
    $bd->query($sQuery);
    
    $r=$bd->getResultatObj();
    
    if ($bd->getErrDescr()!="Ok")
    {
	echo("90 18 Database error: ".$bd->getErrDescr());
	mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	die;
    }
    
    $lastUptime=$r[0]->uptime;
    $lastUptimeDate=$r[0]->reg_date;
    
    
    // calculate theoretical current uptime
    $theoreticalUptime=theoreticalUptime($lastUptime, $lastUptimeDate);
    
    
    // Faked uptime?
    if ($uptime>$theoreticalUptime+$_MAX_FORWARD_DEVIATION)
    {
	echo("04 Provided uptime exceeds theoretical uptime by ".($uptime-$theoreticalUptime)." seconds");
 	mail("zouave@mansoft.org", "uptime", "Exceeds uptime by ".($uptime-$theoreticalUptime)." (".niceUptime($uptime-$theoreticalUptime).").\n\n".getInfo());
	die;
    }
    
    
    // Reboot detected?
    if ($uptime<$theoreticalUptime-$_REBOOT_THRESHOLD)
    {
	// reboot - insert new register
	$sQuery="INSERT INTO uptime(username, machine, reg_date, uptime, ip) VALUES(";
	$sQuery.=dbstr($username).", ".dbstr($nodename).", NOW(), ".dbstr($uptime).", ".dbstr($ipaddr).")";
	$bd->query($sQuery);
	
	if ($bd->getErrDescr()!="Ok")
	{
	    echo("90 18 Database error: ".$bd->getErrDescr());
	    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	    die;
	}    	
    }
    else
    {
	// update uptime value
	
	
	$sQuery="UPDATE uptime SET uptime=".dbstr($uptime).", reg_date=NOW(), ip=".dbstr($ipaddr).", uptime_deviation=".dbstr(($uptime-$theoreticalUptime))." WHERE username=".dbstr($username)." AND machine=".dbstr($nodename)." AND reg_date=".dbstr($lastUptimeDate);
	$bd->query($sQuery);
	
	if ($bd->getErrDescr()!="Ok")
	{
	    echo("90 19 Database error: ".$bd->getErrDescr());
	    mail("zouave@mansoft.org", "uptime", "Database error:\n\n".getInfo()."\n".$bd->getErrDescr());
	    die;
	}    	
    }
}


echo("00 OK");
?>
